﻿/* ***********************************************
 * Author		:  kingthy
 * Email		:  kingthy@gmail.com
 * Description	:  DbObjectExtensions
 *
 * ***********************************************/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Collections.Specialized;
using System.ComponentModel;
 
namespace MX.Core.Data
{
    /// <summary>
    /// 与数据对象相关的扩展方法
    /// </summary>
    public static class DbObjectExtensions
    {
        #region NameValueCollection.ToDbObject
        /// <summary>
        /// 将集合转换为DbObject实例
        /// </summary>
        /// <param name="collection">集合</param>
        /// <returns></returns>
        public static DbObject ToDbObject(this NameValueCollection collection)
        {
            return ToDbObject<DbObject>(collection);
        }
        /// <summary>
        /// 将集合转换为DbObject或DbObject派生类实例
        /// </summary>
        /// <typeparam name="T">类型</typeparam>
        /// <param name="collection">集合</param>
        /// <returns></returns>
        public static T ToDbObject<T>(this NameValueCollection collection)
            where T : DbObject, new()
        {
            T t = new T();
            foreach (string k in collection)
            {
                t.SetDataInternal(k, collection[k]);
            }
            return t;
        }
        #endregion

        #region IDataRecord.ToDbObject
        ///// <summary>
        ///// 将IDataRecord实例转换为DbObject实例
        ///// </summary>
        ///// <param name="record"></param>
        ///// <returns></returns>
        //public static DbObject ToDbObject(this IDataRecord record)
        //{
        //    return ToDbObject<DbObject>(record);
        //}
        ///// <summary>
        ///// 将IDataRecord实例转换为DbObject派生类实例
        ///// </summary>
        ///// <param name="record"></param>
        ///// <returns></returns>
        //public static T ToDbObject<T>(this IDataRecord record)
        //    where T : DbObject, new()
        //{
        //    T t = new T();
        //    record.CopyToDbObject(t);
        //    return t;
        //}
        #endregion

        #region DataTable.ToDbObjectList
        /// <summary>
        /// 将DataTable实例转换为DbObject列表实例
        /// </summary>
        /// <param name="table"></param>
        /// <returns></returns>
        public static List<DbObject> ToDbObjectList(this DataTable table)
        {
            return ToDbObjectList<DbObject>(table);
        }
        /// <summary>
        /// 将DataTable实例转换为DbObject派生类列表实例
        /// </summary>
        /// <param name="table"></param>
        /// <returns></returns>
        public static List<T> ToDbObjectList<T>(this DataTable table)
            where T : DbObject, new()
        {
            List<T> items = new List<T>();
            foreach (DataRow row in table.Rows)
            {
                T t = new T();
                foreach (DataColumn column in table.Columns)
                {
                    t.SetDataInternal(column.ColumnName, row[column]);
                }
                items.Add(t);
            }
            return items;
        }
        #endregion

        #region IDataReader.ToDbObjectList
        ///// <summary>
        ///// 将IDataReader实例转换为DbObject列表实例
        ///// </summary>
        ///// <param name="reader"></param>
        ///// <returns></returns>
        //public static List<DbObject> ToDbObjectList(this IDataReader reader)
        //{
        //    return ToDbObjectList<DbObject>(reader);
        //}
        ///// <summary>
        ///// 将IDataReader实例转换为DbObject派生类列表实例
        ///// </summary>
        ///// <param name="reader"></param>
        ///// <returns></returns>
        //public static List<T> ToDbObjectList<T>(this IDataReader reader)
        //    where T : DbObject, new()
        //{
        //    List<T> items = new List<T>();
        //    while (reader.Read())
        //    {
        //        items.Add(ToDbObject<T>((IDataRecord)reader));
        //    }
        //    return items;
        //}
        #endregion

        #region DbObject.ToDataTable
        /// <summary>
        /// 将数据对象序列转换为System.Data.DataTable对象
        /// </summary>
        /// <param name="dbObjects"></param>
        /// <returns></returns>
        public static DataTable ToDataTable(this IEnumerable<DbObject> dbObjects)
        {
            if (dbObjects == null) return null;
            var ds = dbObjects.FirstOrDefault();
            if (ds == null) return null;

            var properties = TypeDescriptor.GetProperties(ds);
            DataTable table = new DataTable();
            foreach (PropertyDescriptor p in properties)
            {
                table.Columns.Add(p.Name, p.PropertyType);
            }

            bool existing;
            foreach (var d in dbObjects)
            {
                var row = table.NewRow();
                foreach (PropertyDescriptor p in properties)
                {
                    row[p.Name] = d.GetDataInternal(p.Name, out existing);
                }
                table.Rows.Add(row);
            }
            return table;
        }
        #endregion

    }
}
